#include "llvm/AsmParser/Parser.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Bitcode/BitcodeWriter.h"
int main(int Argc, char **Argv) {
  llvm::StringRef IRSrc = "                                   \
  define dso_local i32 @sub(i32 noundef %0, i32 noundef %1) { \
   %3 = sub nsw i32 %0, %1                                    \
   ret i32 %3                                                 \
  }";
  llvm::LLVMContext Ctx;
  llvm::SMDiagnostic Err; // TODO обработка ошибки
  std::unique_ptr<llvm::Module> M =
      llvm::parseAssemblyString(IRSrc, Err, Ctx);
  llvm::Function *F = M->getFunction("sub");
  F->dump();
  auto &BB = F->getEntryBlock();
  llvm::BinaryOperator &I = llvm::cast<llvm::BinaryOperator>(*BB.begin());
  llvm::IRBuilder<> Bld(Ctx);
  Bld.SetInsertPoint(&I);
  auto *Inew = Bld.CreateNSWSub(I.getOperand(1), I.getOperand(0));
  I.replaceAllUsesWith(Inew);
  I.eraseFromParent();
  F->dump();
  std::error_code EC;
  llvm::raw_fd_stream Out("example.bc", EC); // TODO обработка ошибки
  llvm::WriteBitcodeToFile(*M, Out);
}
